#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/12/10 21:46
# @Author  : FuKai ZHANG
# @File    : redis_control.py
# @Description :redis封装，支持字符串设置、获取、删除、批量设置、批量获取、删除所有缓存
from typing import Text, Any, Optional
from config.global_config import config
import redis
from threading import Lock
from typing import Text, Optional, Dict, List
from utils.logging_tools.log_control import INFO


class RedisHandler:
    _pool:Optional[redis.ConnectionPool]=None  # 类变量，线程池共享，如果多进程调用，每个类会有自己的变量，也就是说每个类会有自己的线程池
    _lock = Lock()  # 线程锁，只有一个线程能执行初始化操作

    def __init__(self):
        with RedisHandler._lock:
            if RedisHandler._pool is None:
                RedisHandler._pool = redis.ConnectionPool(
                    host=config.redis_db.host,
                    port=config.redis_db.port,
                    password=config.redis_db.password,
                    db=config.redis_db.db,
                    decode_responses=True,
                    max_connections=20
                )
        self.redis = redis.Redis(connection_pool=RedisHandler._pool)

    def set_hash(self,name:Text,value:Dict,exp_time:Optional[int]=None)->None:
        """
        将字典存储为 Redis Hash
        :param name: Hash 键名（如 case:login_01）
        :param value: 字典数据
        :param exp_time: 过期时间（秒）
        """
        self.redis.hset(name, mapping=value)
        if exp_time:
            self.redis.expire(name, exp_time)

    def get_hash(self, name: Text) -> Dict:
        """
        从 Redis Hash 读取数据
        :param name: Hash 键名
        :return: 字典数据
        """
        return self.redis.hgetall(name)

    def key_exists(self, key: Text) -> bool:
        """
        判断 Redis 中的 key 是否存在
        :param key:
        :return: 布尔值
        """
        return bool(self.redis.exists(key))

    def set_many_hash(self, cases: Dict[str, Dict]) -> None:
        """
        批量设置 Hash 数据
        :param cases: {case_id: case_data} 字典
        """
        pipe = self.redis.pipeline()
        for case_id, case_data in cases.items():
            redis_key = f"case:{case_id}"
            pipe.hset(redis_key, mapping=case_data)
        pipe.execute()

    def get_many_hash(self, case_ids: List[Text]) -> List[Dict]:
        """
        批量获取 Hash 数据
        :param case_ids: 键名列表
        :return: 字典列表
        """
        results = []
        for case_id in case_ids:
            redis_key = f"case:{case_id}"
            hash_data = self.get_hash(redis_key)
            results.append(hash_data)
        return results

    def del_all_cache(self) -> None:
        """
        清理所有缓存
        """
        for key in self.redis.keys():
            self.redis.delete(key)
        INFO.info("清理所有缓存成功！")

    def del_cache(self, name: Text) -> None:
        """
        删除指定缓存
        :param name:
        """
        self.redis.delete(name)

    def set_string(self, name: Text, value: Text) -> None:
        """
        设置字符串缓存
        :param name: 键名
        :param value: 键值
        """
        self.redis.set(name, value, ex=None, px=None, nx=False, xx=False)

    def get_string(self, name: Text) -> Text:
        """
        获取字符串缓存
        :param name: 键名
        :return: 键值
        """
        return self.redis.get(name)


if __name__ == '__main__':
    RedisHandler().del_all_cache()  # 手动删除所有key
#     # print(RedisHandler().get_many(['login_01', 'login_02', 'login_03']))
